package org.cyz.tools.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import org.cyz.tools.common.bean.ResultBean;
import org.cyz.tools.common.util.TreeUtil;
import org.cyz.tools.common.util.*;
import org.cyz.tools.core.ContextManager;
import org.cyz.tools.core.assembly.Notify;
import org.cyz.tools.core.assembly.UIRefresh;
import org.cyz.tools.core.assembly.dialog.DialogBuilder;
import org.cyz.tools.core.assembly.treetable.NodeData;
import org.cyz.tools.core.assembly.treetable.NodeInfo;
import org.cyz.tools.core.assembly.treetable.TreeTableViewCreator;
import org.magiclen.mson.JSONType;
import org.magiclen.mson.Mson;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

/**
 * @program: RedisGUI
 * @description: menu controller
 * @author: Chenyz
 * @create: 2020-08-10 10:21
 **/
public class BodyController extends UIRefresh implements Initializable {
    private RedisUtil redisUtil = new RedisUtil();
    private KeyBoardUtil keyBoardUtil = new KeyBoardUtil();

    @FXML
    public TextArea monitor;

    @FXML
    public ComboBox viewType;

    @FXML
    public TextField keyName;

    @FXML
    public Label valueType;
    @FXML
    public Label valueTTL;
    @FXML
    public Label resultCount;
    @FXML
    public Pane resultPane;
    @FXML
    public AnchorPane bodyPane;
    @FXML
    public TabPane bodyTabPane;
    @FXML
    private TextField searchKey;
    @FXML
    public TextArea showConsole;
    @FXML
    public TextArea inputConsole;
    @FXML
    private Button rename;
    @FXML
    private Button setTTL;


    private final static double width = 550;
    private final static double height = 305;

    private static boolean flag = false;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        monitor.setText("没有建立的连接...\n");
        ContextManager.ctrManager.addController(this.getClass().getSimpleName(), this);
        init();
    }

    private void init() {
        initViewType();
        initListent();
    }

    /**
     * 初始化监听事件
     */
    private void initListent() {
        viewType.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
            @Override
            public void changed(ObservableValue observableValue, Object o, Object t1) {
                switch (t1.toString()) {
                    case "TEXT":
                        break;
//                     case "JSON":break;
//                     case "TreeTable":break;
                    default:
                        break;
                }
            }
        });
        //设置显示的自动换行
        showConsole.setWrapText(true);
        inputConsole.setWrapText(true);
        inputConsole.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent keyEvent) {
                keyBoardUtil.inputEvent(keyEvent, inputConsole);
            }
        });
        inputConsole.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent keyEvent) {
                keyBoardUtil.inputContent(keyEvent, inputConsole, showConsole);
            }
        });

        /**
         * 修改键
         */
        rename.setOnAction(event -> {
            if (null == keyName.getText() || keyName.getText().trim().length() <= 0) {
                Notify.toast("先选择key后再编辑!");
                return;
            }
            //获取旧值
            String oldKey = keyName.getText();
            new DialogBuilder(rename).setTitle("提示").setContent(oldKey).setMessage("输入新的key").setTextFieldText(new DialogBuilder.OnInputListener() {
                @Override
                public void onGetText(String result) {
                    if (null != result) {
                        if (!oldKey.equals(result)) {
                            //执行更新
                            String val = redisUtil.rename(oldKey, result);
                            if ("OK".equalsIgnoreCase(val)) {
                                MainController mc = (MainController) ContextManager.ctrManager.getController(MainController.class.getSimpleName());
                                if (null != mc) {
                                    TreeUtil.updateKey(mc.treeView, result);
                                    TreeUtil.updateKeyCount(mc.treeView);
                                    refreshValue(rename, result);
                                    Notify.toast("修改完成!");
                                } else {
                                    Notify.toast("修改失败!");
                                }
                            }
                        }
                    }
                }
            }).setPositiveBtn("确定").setNegativeBtn("取消").create();
        });

        /**
         * 修改ttl
         */
        setTTL.setOnAction(event -> {
            String sKey = keyName.getText();
            if (null == sKey || sKey.trim().length() <= 0) {
                Notify.toast("不能设置空的key!");
                return;
            }
            Object ttlVal = 0;
            if (valueTTL.getText().split(":").length == 2) {
                ttlVal = valueTTL.getText().split(":")[1];
            }
            new DialogBuilder(setTTL).setTitle("提示").setContent(ttlVal.toString()).setMessage("设置key的有效期(单位:秒)").setTextFieldText(new DialogBuilder.OnInputListener() {
                @Override
                public void onGetText(String result) {
                    if (null != result) {
                        redisUtil.setTTL(sKey, Integer.valueOf(result));
                        valueTTL.setText("键生命周期:" + DateUtil.convTime(Long.valueOf(result)));
                    }
                }
            }).setPositiveBtn("确定").setNegativeBtn("取消").create();
            ;
        });
    }

    private void initViewType() {
        viewType.getItems().addAll(
                "TEXT",
                "JSON",
                "TreeTable"
        );
        viewType.getItems().add("自适应");
        viewType.getSelectionModel().select(0);
    }

    /**
     * 清除控件上次的值
     */
    public void clearOldValue() {
        keyName.clear();
        resultCount.setText("字符数: ");
        resultPane.getChildren().clear();
        valueTTL.setText("生存周期: ");
        valueType.setText("数据类型: ");
    }


    /**
     * TreeTable方式展示
     *
     * @param resultBean
     */
    @Deprecated
    public synchronized void setTreeTablePane(ResultBean resultBean) {
        double layoutX = 0;
        double layoutY = 0;
        String[] columnName = {"键", "值", "备注"};
        String jsonMessage = "{'nodeInfo':{'data1':'我是键','data2':'我是值','data3':'我是备注'},'childNotes':[{'nodeInfo':{'data1':'Child 1','data2':'Child 1 data','data3':'child  1 notes'},'childNotes':[{'nodeInfo':{'data1':'Child 3','data2':'Child 3 data','data3':'Child 3 notes'},'childNotes':[]}]},{'nodeInfo':{'data1':'Child 2','data2':'Child 2 data','data3':'Child 2 notes'},'childNotes':[]}]}";
        double minColumnWidth = 150;
        NodeData nodeData = new NodeData();
        NodeInfo nodeInfo = new NodeInfo();
//        nodeInfo.setData1(resultBean.getKey());
        Platform.runLater(() -> resultCount.setText(resultCount.getText() + resultBean.getLen()));
        switch (resultBean.getValueType()) {
            case "string":
//                nodeInfo.setData2(resultBean.getValue());
                nodeData.setNodeInfo(nodeInfo);
                //传入树表X坐标、Y坐标、宽、高、表头列名、表头列宽、表体内容
                jsonMessage = JSON.toJSONString(nodeData, SerializerFeature.WriteMapNullValue);
                break;
            case "list":
                break;
            case "hash":
                List<NodeData> arrs = new ArrayList<>();
                resultBean.getHkeys().forEach((key) -> {
                    NodeInfo ni = new NodeInfo();
//                    ni.setData1(resultBean.getKey());
//                    ni.setData2(key);
//                    ni.setData3("Hash集合");
                    nodeData.setNodeInfo(ni);
                    arrs.add(nodeData);
                });
                //传入树表X坐标、Y坐标、宽、高、表头列名、表头列宽、表体内容
                jsonMessage = JSON.toJSONString(arrs, SerializerFeature.WriteMapNullValue);
                break;

            case "set":
                break;
            case "zset":
                break;
        }
        TreeTableView parent = new TreeTableViewCreator().createContent(layoutX, layoutY, width, height, columnName, minColumnWidth, jsonMessage);
        //容器尺寸绑定
        parent.prefHeightProperty().bind(resultPane.heightProperty());
        parent.prefWidthProperty().bind(resultPane.widthProperty());
        resultPane.getChildren().add(parent);
    }

    /**
     * JSON方式展示
     *
     * @param resultBean
     */
    @Deprecated
    public void setJsonPane(ResultBean resultBean) {
    }

    /**
     * TEXT方式展示
     *
     * @param resultBean
     */
    @Deprecated
    public void setTextPane(ResultBean resultBean) {
        TextArea textArea = new TextArea();
        textArea.setStyle("-fx-highlight-fill: lightgray; -fx-highlight-text-fill: firebrick; -fx-font-size: 20px;");
        textArea.setPrefHeight(height);
        textArea.setPrefWidth(width);
        textArea.setMinSize(width, height);
        textArea.setWrapText(true);
        textArea.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                mouseEvent.consume();
            }
        });
        Platform.runLater(() -> resultCount.setText(resultCount.getText() + resultBean.getLen()));
        switch (resultBean.getValueType()) {
            case "string":
                textArea.setText(resultBean.getValue());
                break;
            case "list":
                textArea.setText(JSON.toJSONString(resultBean.getListValue()));
                break;
            case "hash":
                textArea.setText(JSON.toJSONString(resultBean.getHashValue()));
                break;
            case "set":
                textArea.setText(JSON.toJSONString(resultBean.getSetValue()));
                break;
            case "zset":
                textArea.setText(JSON.toJSONString(resultBean.getzSetValue()));
                break;
        }
        //容器尺寸绑定
        textArea.prefHeightProperty().bind(resultPane.heightProperty());
        textArea.prefWidthProperty().bind(resultPane.widthProperty());
        resultPane.getChildren().add(textArea);
    }

    /**
     * 根据数据类型自适应显示
     *
     * @param resultBean
     */
    public void setSelfAdaptionResult(ResultBean resultBean) {
        Platform.runLater(() -> resultCount.setText(resultCount.getText() + resultBean.getLen()));
        TextArea textArea = new TextArea();
        textArea.setPrefHeight(height);
        textArea.setPrefWidth(width);
        textArea.setMinSize(width, height);
        textArea.setWrapText(true);
        textArea.setEditable(true);
        //容器尺寸绑定
        textArea.prefHeightProperty().bind(resultPane.heightProperty());
        textArea.prefWidthProperty().bind(resultPane.widthProperty());
        JSONType jsonType = null;
        switch (resultBean.getValueType()) {
            case "string":
                if (resultBean.getValue().contains("[") || resultBean.getValue().contains("{")) {
                    jsonType = Mson.fromString(resultBean.getValue());
                } else {
                    textArea.setText(resultBean.getValue());
                    Platform.runLater(() -> resultPane.getChildren().setAll(textArea));
                    return;
                }
                break;
            case "hash":
                jsonType = Mson.fromString(JSON.toJSONString(resultBean.getHashValue()));
                break;
            case "list":
                jsonType = Mson.fromString(JSON.toJSONString(resultBean.getListValue()));
                break;
            case "set":
                jsonType = Mson.fromString(JSON.toJSONString(resultBean.getSetValue()));
                break;
            case "zset":
                jsonType = Mson.fromString(JSON.toJSONString(resultBean.getzSetValue()));
                break;
        }
        textArea.setText(Mson.toString(jsonType, true));
        Platform.runLater(() -> resultPane.getChildren().setAll(textArea));
    }

    /**
     * 删除key
     */
    public void delKey() {
        if (null != keyName.getText() && keyName.getText().trim().length() > 0) {
            MainController mainController = (MainController) ContextManager.ctrManager.getController(MainController.class.getSimpleName());
            if (null != mainController) {
                if (TreeUtil.delTreeItem(mainController.treeView) && redisUtil.del(keyName.getText())) {
                    clearOldValue();
                    Notify.toast("完成删除!");
                }
            }
        } else {
            Notify.toast("删除的key不能为空!");
        }
    }

    /**
     * 根据key进行检索
     */
    public void search() {
        //先判断下左侧连接是否打开
        if (!RedisUtil.isOpen) {
//            Toast.toast("请先选择您要连接的库(默认搜索DB0)!");
            Notify.dialog("提示","请先选择您要连接的库(默认搜索DB0)!");

            return;
        }
        String sKey = searchKey.getText();
        if (null == sKey || sKey.trim().length() <= 0) {
            Notify.toast("不能检索空的key!");
            return;
        }
        ResultBean resultBean = redisUtil.getValue(sKey);
        if (null == resultBean) {
            Notify.toast("没有检索到匹配的key!");
            return;
        }

        //定位左侧key的位置 TODO: 这个功能后续再考虑
//        MainController mc= (MainController) ContextManager.ctrManager.getController(MainController.class.getSimpleName());
//        if(null!=mc.mTreeView){
//            TreeUtil.indexKey(mc.mTreeView,sKey);
//        }
        clearOldValue();
        //设置键
        keyName.setText(sKey);
        //展示搜索结果
        setSelfAdaptionResult(resultBean);
    }

    public void showLog(Event event) {

    }

    /**
     * 初始化输入控制台
     */
    public void getInput() {
        if (!RedisUtil.isOpen) {
            inputConsole.setPromptText("没有建立连接的数据库!");
            inputConsole.setEditable(false);
            return;
        }
        if (!flag) {
            inputConsole.appendText(ConsoleUtil.consoleHeader());
            inputConsole.setEditable(true);
            flag = true;
        }
    }

    public void historyCommand(Event event) {
    }

    public void sysInfo(Event event) {
        if(RedisUtil.isOpen){
            StringBuffer stringBuffer=new StringBuffer();
            stringBuffer.append("");
        }
    }
}
